package top.huhuiyu.teachproject.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import top.huhuiyu.teachproject.service.RedisService;
import top.huhuiyu.teachproject.utils.JsonUtils;

import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class RedisServiceImpl implements RedisService {
  private final StringRedisTemplate stringRedisTemplate;

  @Override
  public void save(String key, Object data) {
    if (data == null) {
      return;
    }
    ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
    try {
      ops.set(key, JsonUtils.stringify(data));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public void save(String key, Object data, long timeout) {
    if (data == null) {
      return;
    }
    ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
    try {
      ops.set(key, JsonUtils.stringify(data), timeout, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public <T> T get(String key, Class<T> clazz) {
    ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
    try {
      String value = ops.get(key);
      return value == null ? null : JsonUtils.parse(value, clazz);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public void update(String key, Object data) {
    log.debug("更新redis：{},{},{},{}", key, data, stringRedisTemplate.hasKey(key), stringRedisTemplate.getExpire(key));
    if (!Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))) {
      return;
    }
    // 获取过期时间
    Long timeout = stringRedisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
    if (timeout == null || timeout < 0) {
      return;
    }
    save(key, data, timeout);
  }

  @Override
  public Boolean hasKey(String key) {
    return stringRedisTemplate.hasKey(key);
  }
}
